package sc.analysis.aroon;


import java.io.IOException;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import sc.writable.IntermediateData;
import sc.writable.IntermediateData.Type;


/**
 * Reducer of Aroon Technical analysis.
 *
 * @author Quentin Rossé
 *
 */
public class AroonReducer extends Reducer<Text, AroonData, 
                                        Text, IntermediateData> {
	
	private static final String ANALYSIS_NAME = "Aroon";
	
	/**
	 * data written for the next phase
	 */
	private static IntermediateData imd = new IntermediateData();
	
	@Override
	public void reduce(Text key, Iterable<AroonData> values, Context context) throws IOException, InterruptedException {
		boolean cross;
		for(AroonData ad : values){
			
			cross = false;
			imd.setAnalysisName(ANALYSIS_NAME + ad.getPeriod());
			
			if(ad.getPrevDown() < ad.getPrevUp() && ad.getDown() > ad.getUp()){
				cross = true;
				imd.setType(Type.ALERT_BEAR);
				imd.setScore(1);
				imd.setDetails("AroonDown crossed AroonUp");
				context.write(key, imd);
			}
			
			if(ad.getPrevUp() < ad.getPrevDown() && ad.getUp() > ad.getDown()){
				cross = true;
				imd.setType(Type.ALERT_BULL);
				imd.setScore(1);
				imd.setDetails("AroonUp crossed AroonDown");
				context.write(key, imd);
			}
			
			imd.setType(ad.getPeriod());
			imd.setScore(score(ad.getUp(), ad.getDown(), cross));
			imd.setDetails("");
			context.write(key, imd);
		}
	}
	
	@Override
	public void setup(Context context){
		imd.setAnalysisName(ANALYSIS_NAME);
	}
	
	@Override
	public void cleanup(Context context){}
	
	
	/**
	 * Return the score from the value of AroonUp and AroonDown
	 * 
	 * @return
	 */
	private int score(int aroonUp, int aroonDown, boolean cross){
		if((aroonUp >= 50 && aroonDown >= 50) ||
		   (aroonUp <= 50 && aroonDown <= 50)) 
			return 5;
		
		if(aroonUp >= 50){
			if(aroonUp >= 95){
				if(aroonDown < 30){
					if(cross)
						return 10;
					else
						return 9;
				}
				else
					return 7;
			}
			if(aroonUp >= 70 && aroonDown < 30)
				return 7;
			else
				return 6;
		}
		else{
			if(aroonDown >= 95){
				if(aroonUp < 30){
					if(cross)
						return 0;
					else
						return 1;
				}
				else
					return 3;
			}
			if(aroonDown >= 70 && aroonUp < 30)
				return 3;
			else
				return 4;
		}
	}
}